/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful, 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License 
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/
 
Ext.ns('AIR2.UI');
/***************
 * AIR2 TagPanel Component
 *
 * AIR2 Panel for tagging resources
 *
 * @class AIR2.UI.TagPanel
 * @extends AIR2.UI.Panel
 * @xtype air2tagpanel
 * @cfg {Object/Array} storeData
 *   Initial tag data to load store with
 * @cfg {String} url
 *   Restful url for adding/removing tags
 * @cfg {Boolean} allowEdit
 *   False to disable adding/removing tags.  Defaults to true.
 *
 */
AIR2.UI.TagPanel = function(config) {
    config.showTotal = true;
    config.itemSelector = 'li.air2-tag-list-item';
    config.tpl = new Ext.XTemplate(
        '<div style="display:inline-block"><ul class="air2-tag-list">' +
          '<tpl for=".">' +
            '<li class="air2-tag-list-item" {[this.quickTip(values)]}">' +
              '{[AIR2.Format.tagName(values)]}' +
              '<span class="air2-tag-delete-icon"/>' +
            '</li>' +
          '</tpl>' +
        '</ul></div>',
        {
            quickTip: function(values) {
                if (values.tm_type == 'I') {
                    return 'ext:qtip="' + values.IptcMaster.iptc_name + '"';
                }
                return '';
            }
        }
    );

    // create the searchbox for tagmaster records
    this.tagsearch = new AIR2.UI.SearchBox({
        autoCreate: {tag: 'input', type: 'text', autocomplete: 'off', maxlength: '32'},
        maskRe: /[a-zA-Z0-9 _\-\.]/,
        searchUrl: AIR2.HOMEURL + '/tag',
        valueField: 'tm_id',
        displayField: 'tm_name',
        formatComboListItem: function(values) {
            var name = AIR2.Format.tagName(values);
            name = name.replace(this.queryRegExp, '<b>'+this.queryString+'</b>');
            var usage = values.usage ? " (" + values.usage + ")" : '';
            return name + usage;
        },
        formatToolTip: function(values) {
            if (values.tm_type == 'I') {
                return 'ext:qtip="' + values.IptcMaster.iptc_name + '"';
            }
            return '';
        },
        forceSelection: false,
        width: 220,
        allowBlank: true,
        listeners: {
            beforequery: function(queryevent) {
                queryevent.query = this.getRawValue();
                this.tpl.queryString = queryevent.query;
                this.tpl.queryRegExp = new RegExp(queryevent.query, 'i');
            },
            select: function(combo, record, index) {
                if (record.get('tm_type') == 'I') {
                    combo.selectedDisplay = record.data.IptcMaster.iptc_name;
                } else {
                    combo.selectedDisplay = record.get('tm_name');
                }
                combo.setRawValue(combo.selectedDisplay);
            },
            specialkey: {fn: function(combo, e) {
                if (e.getKey() == e.ENTER) {
                    this.addTag();
                }
            }, scope: this}
        }
    });
    var searchArea = new Ext.Container({
        cls: 'tag-add',
        items: [this.tagsearch, {
            xtype: 'air2button',
            air2type: 'BLUE',
            air2size: 'MEDIUM',
            text: 'Add',
            handler: this.addTag,
            scope: this
        }]
    });

    // call parent constructor
    AIR2.UI.TagPanel.superclass.constructor.call(this, config);

    // hide the editing functionality
    if (config.allowEdit == false) {
        this.addClass('read-only');
    }

    // searchbox at the top of the body
    this.getBody().insert(0, searchArea);

    // handle server-side exceptions
    var s = this.getStore();
    s.on('exception', function(proxy, type, action, options, response, arg) {
        if (type == 'response' && action == 'create') {
            // server side error --- remove record and show msg
            s.remove(s.getModifiedRecords());
            this.setStatus(Ext.util.JSON.decode(response.responseText).message, 2000);
        }
    }, this);
    s.on('remove', function() {
        this.setTotal(s.getCount());
    }, this);
    s.on('add', function() {
        this.setTotal(s.getCount());
    }, this);

    // setup click listener
    this.on('afterrender', function() {
        this.el.on('click', function(ev, htmlEl) {
            if (ev.getTarget('.air2-tag-delete-icon')) {
                var d = this.getDataView();
                var r = d.getRecord(ev.getTarget(d.itemSelector));
                s.remove(r);
                s.save();
                var tagname = AIR2.Format.tagName(r.data);
                this.setStatus('Removed tag "'+tagname+'" <a class="air2-button undo">Undo</a>');
                this.undoRec = r;
            }
            else if (ev.getTarget('.undo')) {
                this.setStatus(false);
                if (this.undoRec.get('tm_type') == 'I') {
                    this.addExistingTag(this.undoRec);
                }
                else {
                    this.addNewTag(this.undoRec.get('tm_name'));
                }
            }

        }, this);
    }, this);
}
Ext.extend(AIR2.UI.TagPanel, AIR2.UI.Panel, {
    cls: 'air2-panel air2-tagpanel',
    addTag: function() {
        var raw = this.tagsearch.getRawValue().trim();
        if (raw.length > 0) {
            this.setStatus(false);
            var rec = this.tagsearch.getSelectedRecord();
            if (raw == this.tagsearch.selectedDisplay) {
                this.addExistingTag(rec);
            } else {
                this.addNewTag(raw);
            }
        }
        this.tagsearch.clearValue();
    },
    addExistingTag: function(rec) {
        var s = this.getStore();
        var addtag = new s.recordType({
            tm_id: rec.get('tm_id'),
            tm_name: rec.get('tm_name'),
            tm_type: rec.get('tm_type'),
            IptcMaster: rec.get('IptcMaster')
        });
        s.add(addtag);
        s.save();
    },
    addNewTag: function(tagName) {
        var s = this.getStore();
        var addtag = new s.recordType({
            tm_name: tagName
        });
        s.add(addtag);
        s.save();
    },
    setStatus: function(msg, timeoutMs) {
        if (!this.status) {
            this.status = this.body.el.insertSibling({cls: 'tag-status'});
            this.status.sequenceFx();
        }

        var s = this.status, l = this.body.el, o = this.status.opened;
        if (msg) {
            s.opened = true;
            if (o) {
                s.update(msg);
                s.alignTo(l, 'b-b', [0,-5]);
            }
            else {
                s.shift({
                    duration: 0,
                    callback: function() {
                        s.update(msg);
                        s.alignTo(l, 'b-b', [0,-5]);
                        s.slideIn('b', {duration:0.1});
                    }
                });
            }
        }
        else {
            s.opened = false;
            if (o) s.slideOut('b', {duration:0.1});
        }
    },
    getStore: function() {
        return this.getDataView().store;
    },
    getDataView: function() {
        return this.getBody().get(1);
    }
});
Ext.reg('air2tagpanel', AIR2.UI.TagPanel);
